package com.example.readerapp.MyWebView;

import android.annotation.SuppressLint;
import android.content.ClipboardManager;
import android.content.Context;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.text.Selection;
import android.util.AttributeSet;
import android.view.*;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.widget.LinearLayout;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.example.readerapp.R;
import com.example.readerapp.myandserver.mybookconfig.MyBookConfig;
import com.example.readerapp.myandserver.util.FileUtil;
import com.example.readerapp.myandserver.util.MediaPlayUtil;

import java.io.File;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

//自定义实现的webview，拦截系统选中菜单并显示自定义的内容
/*
* 在布局文件中的使用：
*  <com.example.readerapp.MyWebView.MyWebView
            android:id="@+id/wv_webview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="invisible"
    />
*
* */
public class MyWebView extends WebView
{
    Context context=this.getContext();
    WebView myWebView=this;
    TextToSpeech tts;
    MediaPlayUtil mediaPlayUtil;
    float speed=1.0f;
    Handler handler=new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg)
        {
            switch ((msg.what))
            {
                case 1://tts播放/输出至文件完闭
                {
                    try
                    {
                        File f=new File(MyBookConfig.tempTTSPath);
                        if(!f.exists()||f.length()==0)
                        {
                           // Toast.makeText(context,"case_1\n"+"转音频失败", Toast.LENGTH_SHORT).show();
                            //文件转换结束
                            String js ="try{let button=document.querySelector(\".TTSButton\");button.innerHTML=\"朗读\";clearInterval(convertWhetherOver)}catch(e){alert(e)}";
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
                            {  //android系统4.4以上的时候调用js方法用这个
                                myWebView.evaluateJavascript("javascript:" + js, null);

                            }
                            else
                            {
                                myWebView.loadUrl("javascript:" + js);

                            }
                            break;
                        }
                        mediaPlayUtil=new MediaPlayUtil(MyBookConfig.tempTTSPath);
                        //文件转换结束
                        String js ="try{let button=document.querySelector(\".TTSButton\");button.innerHTML=\"暂停\";let stop=document.querySelector(\".zhanwei .StopTTS\");stop.style.display='block';;clearInterval(convertWhetherOver)}catch(e){alert(e)}";
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
                        {  //android系统4.4以上的时候调用js方法用这个
                            myWebView.evaluateJavascript("javascript:" + js, null);

                        }
                        else
                        {
                            myWebView.loadUrl("javascript:" + js);

                        }
                        mediaPlayUtil.startPlay(new MediaPlayer.OnCompletionListener()//播放结束回调
                        {
                            @Override
                            public void onCompletion(MediaPlayer mp)
                            {
                                try
                                {
                                    mp.release();
                                    String js = "try{let button=document.querySelector(\".TTSButton\");button.innerHTML=\"朗读\";let stop=document.querySelector(\".zhanwei .StopTTS\");if(stop!==null) stop.style.display='none';\n}catch(e){alert(e)}";
                                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
                                    {  //android系统4.4以上的时候调用js方法用这个
                                        myWebView.evaluateJavascript("javascript:" + js, null);
                                    }
                                    else
                                    {
                                        myWebView.loadUrl("javascript:" + js);
                                    }
                                }
                                catch (Exception e)
                                {
                                    Toast.makeText(context, 432+"startPlay回调\n"+e.toString(), Toast.LENGTH_SHORT).show();;
                                }
                            }
                        },speed);
                    }catch (Exception e)
                    {
                        Toast.makeText(context,1232+"case1\n"+ e.toString(), Toast.LENGTH_SHORT).show();

                    }
                    break;
                }
                case 2://暂停播放
                {
                    try
                    {
                        if(mediaPlayUtil!=null)
                        mediaPlayUtil.pausePlay();
                    }catch (Exception e)
                    {
                        Toast.makeText(context, 12209+"case2\n"+e.toString(), Toast.LENGTH_SHORT).show();
                    }
                    break;
                }
                case 3://继续播放
                {
                    try
                    {
                        if(mediaPlayUtil!=null)
                        mediaPlayUtil.continuePlay(speed);
                    }catch (Exception e)
                    {
                        Toast.makeText(context,786+"case3\n"+ e.toString(), Toast.LENGTH_SHORT).show();
                    }
                    break;
                }
                case 4://停止播放
                {
                    try
                    {
                        if(mediaPlayUtil!=null)
                            mediaPlayUtil.stopPlay();
                        String js ="try{let button=document.querySelector(\".TTSButton\");if(button!==null) button.innerHTML=\"朗读\";let stop=document.querySelector(\".zhanwei .StopTTS\");if(stop!==null) stop.style.display='none';if(convertWhetherOver!==undefined) clearInterval(convertWhetherOver)}catch(e){}";
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
                        {  //android系统4.4以上的时候调用js方法用这个
                            myWebView.evaluateJavascript("javascript:" + js, null);

                        }
                        else
                        {
                            myWebView.loadUrl("javascript:" + js);

                        }
                    }catch (Exception e)
                    {
                        Toast.makeText(context, 12067+"case4\n"+e.toString(), Toast.LENGTH_SHORT).show();
                    }
                    break;
                }

                case 5:{//异常处理
                    try
                    {
                        if(mediaPlayUtil!=null)
                            mediaPlayUtil.stopPlay();
                        String js ="try{let button=document.querySelector(\".TTSButton\");if(button!==null) button.innerHTML=\"朗读\";let stop=document.querySelector(\".zhanwei .StopTTS\");if(stop!==null) stop.style.display='none';if(convertWhetherOver!==undefined) clearInterval(convertWhetherOver)}catch(e){}";
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
                        {  //android系统4.4以上的时候调用js方法用这个
                            myWebView.evaluateJavascript("javascript:" + js, null);

                        }
                        else
                        {
                            myWebView.loadUrl("javascript:" + js);

                        }
                    }catch (Exception e)
                    {
                        Toast.makeText(context, 1207+"case5\n"+e.toString(), Toast.LENGTH_SHORT).show();
                    }
                    break;
                }
            }
        }
    };

    public MyWebView(@NonNull Context context)
    {
        super(context);
        linkJSInterface();


    }
    /*必须实现下面的构造方法*/
   public MyWebView(Context context,AttributeSet attrs)
   {

       super(context, attrs);
       linkJSInterface();

   }
    public MyWebView(Context context, AttributeSet attrs, int defStyleAttr) {

       super(context, attrs, defStyleAttr, 0);
        linkJSInterface();
    }


    /*覆写View.class的方法*/
    @Override
    public ActionMode startActionMode(ActionMode.Callback callback)
    {
        //callback=myCallback;
        ActionMode actionMode=super.startActionMode(callback);
       return resolveItem(actionMode);
       // return actionMode;
    }
    @Override
    public ActionMode startActionMode(ActionMode.Callback callback, int type){
      //  callback=myCallback;
        ActionMode actionMode =  super.startActionMode(callback, type);
         return resolveItem(actionMode);
        //return actionMode;
    }

    ActionMode temp=null;
    private  ActionMode resolveItem(ActionMode actionMode)
    {
        if(actionMode!=null)
        {
            temp=actionMode;
            Menu menu=actionMode.getMenu();//这个好像是选中文本之后弹出的框子里面的元素的菜单
            menu.clear();//清空系统的弹出框的元素
            //随便往弹出的菜单加点东西
            List<Integer> actionList=new ArrayList<>();
            menu.add("翻译");
            menu.add("复制");
            menu.add("翻译");
            //定义点击事件
            WebView webView=this;
            for(int i=0;i<menu.size();i++)
            {
                MenuItem menuItem = menu.getItem(i);
                menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener()
                {
                    @Override
                    public boolean onMenuItemClick(@NonNull MenuItem item)
                    {
                        //得到的就是menu添加的标题名称
                        String title=item.getTitle().toString();
                        if(title.equals("翻译"))
                        {
                            selectedAndTranslate();
                        }
                        else if(title.equals("复制"))
                        {
                            copySelected();
                        }
                        //不加这个点击点击之后仍是选中状态
                        if(temp!=null)
                        {
                            temp.finish();
                            temp=null;
                        }
                        return true;
                    }
                });
            }

        }
        return actionMode;
    }
    /**
     * 点击的时候，获取网页中选择的文本，回掉到原生中的js接口
       */
    private void selectedAndTranslate() {


        //结尾要带分号
        //有比较大的概率获取不到文本
        String js = "(function getSelectedText() {" +
                 "try{" +
                /*"var txt=\"\";" +
                "if (window.getSelection) {" +
                "txt = window.getSelection().toString();" +
                "} else if (window.document.getSelection) {" +
                "txt = window.document.getSelection().toString();" +
                "} else if (window.document.selection) {" +
                "txt = window.document.selection.createRange().text;" +
                "};console.log(txt);" +
                "if(txt==undefined||txt==null||txt==\"\") alert(\"#\"+txt+\"#\"+selectedText+\"#\");"*/
                "try{/*myJSInterface.callback(selectedText)*/}catch(e){alert(e.toString)};"+
                "getTranslateFromBaiduAndShowWithPopup(selectedText);selectedText=\"\"" +//函数和selectedText变量(通过注册selectchanging监听器获取文本，还是有概率无法获取到选中的文本)在lookbook.html中定义
                ";" +
                "}catch(e){alert(e.toString())}" +
                "})()";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {  //android系统4.4以上的时候调用js方法用这个
            evaluateJavascript("javascript:" + js, null);
        } else {
            loadUrl("javascript:" + js);
        }
    }
    /**
     * 复制选中的文本
     * */
    private void copySelected()
    {
        String js = "(function getSelectedText() {" +
                "var txt;" +
                "if (window.getSelection) {" +
                "txt = window.getSelection().toString();" +
                "} else if (window.document.getSelection) {" +
                "txt = window.document.getSelection().toString();" +
                "} else if (window.document.selection) {" +
                "txt =selectedText;" +
                "};document.execCommand(\"Copy\");" +
                ";" +
                "})()";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {  //android系统4.4以上的时候调用js方法用这个
            evaluateJavascript("javascript:" + js, null);
            Toast.makeText(this.getContext(),"复制成功",Toast.LENGTH_SHORT).show();

        } else {
            loadUrl("javascript:" + js);
            Toast.makeText(this.getContext(),"复制成功",Toast.LENGTH_SHORT).show();
        }
    }


    //调用此函数为前端添加一个js函数，可通过此函数与webview交互
    //函数名称为第二个参数
    //函数参数与注解的函数的参数一致
    //前端使用：
    //myTTS.callback("回调参数")
    //必须在webview的构造函数中使用
    class MyOnInitListener implements TextToSpeech.OnInitListener{

        @Override
        public void onInit(int status)
        {

        }
    }

    @SuppressLint("JavascriptInterface")
    private void linkJSInterface()
    {
        addJavascriptInterface(new Object(){
            @JavascriptInterface
            public void callback(String value,float rate){
           //   Toast.makeText(context,"回调参数:"+rate,Toast.LENGTH_SHORT).show();
                try
                {
                    String modifyValue=value;
                    //必须在onInit中朗读，模拟器可能出不了声音需要安装引擎
                    tts = new TextToSpeech(context, new TextToSpeech.OnInitListener()
                    {
                        @Override
                        public void onInit(int status)
                        {
                            // 如果装载TTS引擎成功
                            if (status == TextToSpeech.SUCCESS)
                            {
                                // 设置使用美式英语朗读
                                int result = tts.setLanguage(Locale.UK);
                                // 如果不支持所设置的语言
                                if (result != TextToSpeech.LANG_COUNTRY_AVAILABLE && result != TextToSpeech.LANG_AVAILABLE)
                                {
                                    Toast.makeText(context, "TTS暂时不支持这种语言的朗读。", Toast.LENGTH_LONG).show();
                                }
                                // 设置音调,值越大声音越尖（女生），值越小则变成男声,1.0是常规
                                tts.setPitch(1.0f);
                                // 设定语速,默认1.0正常语速
                                tts.setSpeechRate(rate);
                                speed = rate;
                                if(modifyValue.toCharArray().length<4000)
                                {
                                    //执行朗读
                                    // Toast.makeText(context, value, Toast.LENGTH_LONG).show();
                                    //有字数限制
                                    //tts.speak(value,TextToSpeech.QUEUE_FLUSH,null);
                                    //不会阻塞线程，在文件输出结束前，isSpeaking()为true
                                    //最大转换4000个字符(4000个char类型)
                                    tts.synthesizeToFile(modifyValue, null, new File(MyBookConfig.tempTTSPath), "myRecord");
                                    // tts.stop();// 不管是否正在朗读TTS都被打断
                                    //tts.shutdown(); // 关闭，释放资源
                                }
                                else
                                {
                                    //此时会得到一个长度为0的文件
                                    tts.synthesizeToFile(modifyValue,null,new File(MyBookConfig.tempTTSPath),"forShow");
                                    Toast.makeText(context, "文本过长", Toast.LENGTH_LONG).show();
                                }
                            }
                            else
                                Toast.makeText(context, "TTS初始化失败。"+status, Toast.LENGTH_LONG).show();
                        }
                    });
                }catch (Exception e)
                {
                    Toast.makeText(context,-12+"StartMyTTS\n"+e.toString(),Toast.LENGTH_SHORT).show();
                }
            }

        },"StartMyTTS");//接下来由前端不断请求判断是否转换结束
        addJavascriptInterface(new Object(){
            @JavascriptInterface
            public void callback()
            {
                try
                {
                    Message message=new Message();
                    message.what=4;
                    handler.sendMessage(message);
                }
                catch (Exception e)
                {
                    Toast.makeText(context,-222+"StopMyTTS\n"+e.toString(),Toast.LENGTH_SHORT).show();
                }
            }
        },"StopMyTTS");
        addJavascriptInterface(new Object(){
            @JavascriptInterface
            public void callback()
            {
                try
                {
                    if(tts!=null)
                    {
                        Message message=new Message();
                        message.what=2;
                        handler.sendMessage(message);
                    }
                }
                catch (Exception e)
                {
                    Toast.makeText(context,909+"PauseMyTTS\n"+e.toString(),Toast.LENGTH_SHORT).show();
                }
            }
        },"PauseMyTTS");
        addJavascriptInterface(new Object(){
            @JavascriptInterface
            public void callback(float rate)
            {
                try
                {
                    if(tts!=null)
                    {
                        speed=rate;
                        Message message=new Message();
                        message.what=3;
                        handler.sendMessage(message);

                    }
                }
                catch (Exception e)
                {
                    Toast.makeText(context,221+"ContinueMyTTS\n"+e.toString(),Toast.LENGTH_SHORT).show();
                }
            }
        },"ContinueMyTTS");
        addJavascriptInterface(new Object(){//前端循环查询是否转换音频结束
            @JavascriptInterface
            public void callback()
            {
                try
                {
                    if(tts!=null)
                    {
                        if (!tts.isSpeaking())//已经结束(输出至文件或朗读结束)
                        {
                            tts.shutdown();
                            Message message=new Message();
                            message.what=1;
                            handler.sendMessage(message);
                            /*不能这样子，会报错
                            String js = "let button=document.querySelector(\".TTSButton\")\n" + "        button.innerHTML=\"朗读\"  clearInterval(speechWhetherOver)";
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {  //android系统4.4以上的时候调用js方法用这个
                                evaluateJavascript("javascript:" + js, null);
                            } else {
                                loadUrl("javascript:" + js);
                            }*/
                        }
                    }
                }
                catch (Exception e)
                {
                   Toast.makeText(context,109222+"ConvertWhetherOver_EXCEPTION\n"+e.toString(),Toast.LENGTH_LONG).show();
                    tts.shutdown();
                    Message message=new Message();
                    message.what=5;
                    handler.sendMessage(message);
                }
            }
        },"ConvertWhetherOver");

    }


}
